<?php

declare(strict_types=1);

namespace Dongasai\WkProtoPhp\Packets;

use Dongasai\WkProtoPhp\Enums\FrameType;
use Dongasai\WkProtoPhp\Exception\DecodingException;
use Dongasai\WkProtoPhp\Framer;
use Dongasai\WkProtoPhp\Encoder;
use Dongasai\WkProtoPhp\Decoder;

class EventPacket extends Framer
{
    protected string $id = '';
    protected string $type = '';
    protected int $timestamp = 0;
    protected string $data = '';

    public function getFrameType(): int
    {
        return FrameType::EVENT->value;
    }

    public function getId(): string
    {
        return $this->id;
    }

    public function setId(string $id): self
    {
        $this->id = $id;
        return $this;
    }

    public function getType(): string
    {
        return $this->type;
    }

    public function setType(string $type): self
    {
        $this->type = $type;
        return $this;
    }

    public function getTimestamp(): int
    {
        return $this->timestamp;
    }

    public function setTimestamp(int $timestamp): self
    {
        $this->timestamp = $timestamp;
        return $this;
    }

    public function getData(): string
    {
        return $this->data;
    }

    public function setData(string $data): self
    {
        $this->data = $data;
        return $this;
    }

    public static function decodePacket(Framer $framer, string $data): self
    {
        $packet = new self();
        $packet->setFrameType($framer->getFrameType());
        $packet->setRemainingLength($framer->getRemainingLength());
        $packet->setNoPersist($framer->getNoPersist());
        $packet->setRedDot($framer->getRedDot());
        $packet->setSyncOnce($framer->getSyncOnce());
        $packet->setDUP($framer->getDUP());
        
        $decoder = new Decoder($data);
        
        try {
            // 事件ID
            $packet->setId($decoder->string());
            
            // 事件类型
            $packet->setType($decoder->string());
            
            // 事件时间戳
            $packet->setTimestamp($decoder->int64());
            
            // 事件数据 - 读取剩余的所有数据
            $packet->setData($decoder->bytes($decoder->len()));
            
        } catch (\Throwable $e) {
            throw new DecodingException('解码EventPacket失败: ' . $e->getMessage(), 0, $e);
        }
        
        return $packet;
    }

    public function encode(): string
    {
        $encoder = new Encoder();
        
        // 事件ID
        $encoder->writeString($this->id);
        
        // 事件类型
        $encoder->writeString($this->type);
        
        // 事件时间戳
        $encoder->writeInt64($this->timestamp);
        
        // 事件数据
        $encoder->writeBytes($this->data);
        
        return $encoder->getBuffer();
    }

    public function encodeSize(): int
    {
        $size = 0;
        $size += 2 + strlen($this->id); // Id
        $size += 2 + strlen($this->type); // Type
        $size += 8; // Timestamp (int64)
        $size += strlen($this->data); // Data
        return $size;
    }

    /**
     * 获取事件类型（向后兼容）
     */
    public function getEventType(): string
    {
        return $this->type;
    }

    /**
     * 获取事件数据（向后兼容）
     */
    public function getEventData(): string
    {
        return $this->data;
    }
}